package oa.hleast.xswl.service.pms.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import oa.hleast.common.web.exception.BizException;
import oa.hleast.common.web.util.RequestUtils;
import oa.hleast.xswl.common.constant.ReviewStatusEnum;
import oa.hleast.xswl.mapper.oms.OmsOrderCommentMapper;
import oa.hleast.xswl.mapper.oms.OmsOrderCommentReplyMapper;
import oa.hleast.xswl.mapper.pms.PmsSpuMapper;
import oa.hleast.xswl.mapper.store.StoreInfoMapper;
import oa.hleast.xswl.pojo.bo.admin.AdminProductBO;
import oa.hleast.xswl.pojo.bo.app.AppProductBO;
import oa.hleast.xswl.pojo.domain.oms.OmsOrderComment;
import oa.hleast.xswl.pojo.domain.oms.OmsOrderCommentReply;
import oa.hleast.xswl.pojo.domain.pms.*;
import oa.hleast.xswl.pojo.domain.store.StoreInfo;
import oa.hleast.xswl.pojo.dto.SysUserDto;
import oa.hleast.xswl.pojo.dto.pms.SpuDTO;
import oa.hleast.xswl.pojo.dto.store.StoreInfoDto;
import oa.hleast.xswl.pojo.vo.oms.OmsOrderCommentReplyVo;
import oa.hleast.xswl.pojo.vo.oms.OmsOrderCommentVo;
import oa.hleast.xswl.pojo.vo.pms.ShowSpuVo;
import oa.hleast.xswl.pojo.vo.store.BaseStoreInfo;
import oa.hleast.xswl.service.ISysUserService;
import oa.hleast.xswl.service.pms.*;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @Author 00209
 * @Date 2021/03/01 22:01:45
 */
@Slf4j
@Transactional
@Service
@AllArgsConstructor
public class PmsSpuServiceImpl extends ServiceImpl<PmsSpuMapper, PmsSpu> implements IPmsSpuService {

    private ISysUserService sysUserService;
    private IPmsSkuService iPmsSkuService;
    private IPmsSpuAttrValueService iPmsSpuAttrValueService;
    private IPmsSpuSpecValueService iPmsSpuSpecValueService;
    private IPmsCategorySpecService iPmsCategorySpecService;
    private final SpuReviewLogService spuReviewLogService;
    private final OmsOrderCommentMapper commentMapper;
    private final OmsOrderCommentReplyMapper replyMapper;


    @Override
    public IPage<PmsSpu> list(Page<PmsSpu> page, PmsSpu spu) {
        List<PmsSpu> list = this.baseMapper.list(page, spu);
        page.setRecords(list);
        return page;
    }

    /**
     * @param page
     * @param spu
     * @return page
     * 展示在售的商品信息
     */
    @Override
    public IPage<PmsSpu> inStockList(Page<PmsSpu> page, PmsSpu spu) {
        List<PmsSpu> list = this.baseMapper.inStockList(page, spu);
        page.setRecords(list);
        return page;
    }

    @Override
    @Transactional
    public boolean add(AdminProductBO spuBO) {
        Long userId = RequestUtils.getUserId();
        SysUserDto userDto = sysUserService.getSysUserDtoById(userId);
        // 校验验商家信息
        check(userDto);


        SpuDTO spuDTO = spuBO.getSpu();
        List<PmsSpuAttrValue> attrs = spuBO.getAttrs();
        List<PmsSpuSpecValue> specs = spuBO.getSpecs();
        List<PmsSku> skuList = spuBO.getSkuList();

        // spu保存
        PmsSpu spu = new PmsSpu();
        BeanUtil.copyProperties(spuDTO, spu);
        if (spu.getJumpType() == null) {
            spu.setJumpType(0);  //设置初始化状态
        }
        if (spuDTO.getPicUrls() != null) {
            String picUrls = JSONUtil.toJsonStr(spuDTO.getPicUrls());
            spu.setPicUrls(picUrls);
        }
        // 添加店铺ID
        spu.setStatus(0);
        spu.setStoreId(userDto.getStoreId());
        this.save(spu);

        // 属性保存
        Optional.ofNullable(attrs).ifPresent(list -> {
            list.forEach(item -> item.setSpuId(spu.getId()));
            iPmsSpuAttrValueService.saveBatch(list);
        });

        // 规格保存
        Optional.ofNullable(specs).ifPresent(list -> {
            list.forEach(item -> item.setSpuId(spu.getId()));
            iPmsSpuSpecValueService.saveBatch(list);
        });

        // sku保存
        Optional.ofNullable(skuList).ifPresent(list -> {
            list.forEach(item -> item.setSpuId(spu.getId()));
            iPmsSkuService.saveBatch(skuList);
        });

        return true;
    }

    private void check(SysUserDto userDto) {
        //检验是否是商家账号
        log.info("haveStore = {} ,userDto = {} ", userDto.getHaveStore(), userDto);
        if (ObjectUtils.isEmpty(userDto) || !userDto.getHaveStore()) {
            throw new BizException("您还不是商家,权限不足");
        }

        // 检验商店状态 是否是开店
        StoreInfoDto storeInfoDto = userDto.getStoreInfoDto();
        System.out.println("storeInfoDto = " + storeInfoDto);
        Integer storeEventStatus = storeInfoDto.getStoreEventStatus();
        if (1 == storeEventStatus) {
            throw new BizException("您的店铺已关闭,暂无权限发布商品");
        }

        ReviewStatusEnum anEnum = ReviewStatusEnum.getValue(storeInfoDto.getReviewStatus());
        switch (Objects.requireNonNull(anEnum)) {
            case PASS:
                break;
            case UN_KNOWN:
                throw new BizException("您的店铺还未审核,请耐心等待");
            case NO_PASS:
                throw new BizException("您提交的店铺资料有问题,请重新提交");
            default:
                throw new BizException("店铺审核状态异常");
        }
    }

    @Override
    public AdminProductBO getBySpuId(Long id) {
        // spu
        SpuDTO spuDTO = new SpuDTO();
        PmsSpu spu = this.getById(id);
        BeanUtil.copyProperties(spu, spuDTO);

        if (StrUtil.isNotBlank(spu.getPicUrls())) {
            // spu专辑图片转换处理 json字符串 -> List
            List<String> pics = JSONUtil.toList(JSONUtil.parseArray(spu.getPicUrls()), String.class);
            spuDTO.setPicUrls(pics);
        }

        // 属性
        List<PmsSpuAttrValue> attrs = iPmsSpuAttrValueService.
                list(new LambdaQueryWrapper<PmsSpuAttrValue>().eq(PmsSpuAttrValue::getSpuId, id));
        // 规格
        List<PmsSpuSpecValue> specs = iPmsSpuSpecValueService.list(new LambdaQueryWrapper<PmsSpuSpecValue>().eq(PmsSpuSpecValue::getSpuId, id));
        // sku
        List<PmsSku> skuList = iPmsSkuService.list(new LambdaQueryWrapper<PmsSku>().eq(PmsSku::getSpuId, id));

        // 组合
        AdminProductBO spuBO = new AdminProductBO(spuDTO, attrs, specs, skuList);
        return spuBO;
    }


    @Override
    public boolean updateById(AdminProductBO spuBO) {
        SpuDTO spuDTO = spuBO.getSpu();
        Long userId = RequestUtils.getUserId();
        SysUserDto sysUserDto = sysUserService.getSysUserDtoById(userId);
        PmsSpu pmsSpu = this.getById(spuDTO.getId());
        checkMyselfSpu(pmsSpu.getStoreId(), sysUserDto.getStoreId());

        List<PmsSpuAttrValue> attrs = spuBO.getAttrs();
        List<PmsSpuSpecValue> specs = spuBO.getSpecs();
        List<PmsSku> skuList = spuBO.getSkuList();

        // spu保存
        PmsSpu spu = new PmsSpu();
        BeanUtil.copyProperties(spuDTO, spu);
        if (spuDTO.getPicUrls() != null) {
            String picUrls = JSONUtil.toJsonStr(spuDTO.getPicUrls());
            spu.setPicUrls(picUrls);
        }

        // 商品提交审核后 ,修改数据状态变为下架状态 未提交审核 待审核
        if (pmsSpu.getApplyFor().equals(1)) {
            log.info("spuId = {}", spuDTO.getId());
            pmsSpu.setReviewStatus(0);
            pmsSpu.setReviewRemark("");
            pmsSpu.setStatus(1);
            pmsSpu.setApplyFor(0);
        }

        this.updateById(spu);

        // 属性保存
        Optional.ofNullable(attrs).ifPresent(list -> {
            list.forEach(item -> item.setSpuId(spu.getId()));

            // 删除此次保存删除的
            List<Long> ids = list.stream().map(item -> item.getId()).collect(Collectors.toList());
            List<Long> dbIds = iPmsSpuAttrValueService.list(new LambdaQueryWrapper<PmsSpuAttrValue>().eq(PmsSpuAttrValue::getSpuId, spu.getId())
                            .select(PmsSpuAttrValue::getId))
                    .stream()
                    .map(item -> item.getId())
                    .collect(Collectors.toList());
            List<Long> removeIds = dbIds.stream().filter(id -> !ids.contains(id)).collect(Collectors.toList());
            iPmsSpuAttrValueService.removeByIds(removeIds);

            iPmsSpuAttrValueService.saveOrUpdateBatch(list);
        });

        // 规格保存
        Optional.ofNullable(specs).ifPresent(list -> {
            list.forEach(item -> item.setSpuId(spu.getId()));

            // 删除此次保存删除的
            List<Long> ids = list.stream().map(item -> item.getId()).collect(Collectors.toList());
            List<Long> dbIds = iPmsSpuSpecValueService.list(new LambdaQueryWrapper<PmsSpuSpecValue>().eq(PmsSpuSpecValue::getSpuId, spu.getId())
                            .select(PmsSpuSpecValue::getId))
                    .stream()
                    .map(item -> item.getId())
                    .collect(Collectors.toList());
            List<Long> removeIds = dbIds.stream().filter(id -> !ids.contains(id)).collect(Collectors.toList());
            iPmsSpuSpecValueService.removeByIds(removeIds);

            iPmsSpuSpecValueService.saveOrUpdateBatch(list);
        });

        // sku保存
        Optional.ofNullable(skuList).ifPresent(list -> {
            list.forEach(item -> item.setSpuId(spu.getId()));

            // 删除此次保存删除的
            List<Long> ids = list.stream().map(item -> item.getId()).collect(Collectors.toList());
            List<Long> dbIds = iPmsSkuService.list(new LambdaQueryWrapper<PmsSku>().eq(PmsSku::getSpuId, spu.getId())
                            .select(PmsSku::getId))
                    .stream()
                    .map(item -> item.getId())
                    .collect(Collectors.toList());
            List<Long> removeIds = dbIds.stream().filter(id -> !ids.contains(id)).collect(Collectors.toList());
            iPmsSkuService.removeByIds(removeIds);

            iPmsSkuService.saveOrUpdateBatch(skuList);
        });
        return true;
    }

    /**
     * 检查是否一致商品名称,简介,主图,图册
     *
     * @param pmsSpu 旧的商品参数
     * @param spuDTO 新的商品参数
     * @return 是否一致
     */
    private boolean checkIsUpdateParam(PmsSpu pmsSpu, SpuDTO spuDTO) {
        String nameOld = pmsSpu.getName();
        String nameNew = spuDTO.getName();
        if (!nameOld.equals(nameNew)) {
            return true;
        }

        String descriptionOld = pmsSpu.getDescription();
        String descriptionNew = spuDTO.getDescription();
        if (!descriptionOld.equals(descriptionNew)) {
            return true;
        }

        String picUrlOld = pmsSpu.getPicUrl();
        String picUrlNew = spuDTO.getPicUrl();
        if (picUrlOld.equals(picUrlNew)) {
            return true;
        }

        String picUrlsOld = pmsSpu.getPicUrls();
        String picUrlsNew = String.join(",", spuDTO.getPicUrls());
        if (picUrlsOld.equals(picUrlsNew)) {
            return true;
        }

        return false;
    }

    @Override
    public boolean removeBySpuIds(List<Long> spuIds) {
        Optional.ofNullable(spuIds).ifPresent(
                ids -> ids.forEach(spuId -> {
                    // sku
                    iPmsSkuService.remove(new LambdaQueryWrapper<PmsSku>().eq(PmsSku::getSpuId, spuId));
                    // 规格
                    iPmsSpuSpecValueService.remove(new LambdaQueryWrapper<PmsSpuSpecValue>().eq(PmsSpuSpecValue::getId, spuId));
                    // 属性
                    iPmsSpuAttrValueService.remove(new LambdaQueryWrapper<PmsSpuAttrValue>().eq(PmsSpuAttrValue::getSpuId, spuId));
                    // spu
                    this.removeById(spuId);
                })
        );
        return true;
    }


    @Override
    public AppProductBO getProductByIdForApp(Long spuId) {
        // spu
        PmsSpu spu = this.getById(spuId);
        SpuDTO spuDTO = new SpuDTO();
        BeanUtil.copyProperties(spu, spuDTO);
        if (StrUtil.isNotBlank(spu.getPicUrls())) {
            // spu专辑图片转换处理 json字符串 -> List
            List<String> pics = JSONUtil.toList(JSONUtil.parseArray(spu.getPicUrls()), String.class);
            spuDTO.setPicUrls(pics);
        }
        // 属性
        List<PmsSpuAttrValue> attrs = iPmsSpuAttrValueService.list(
                new LambdaQueryWrapper<PmsSpuAttrValue>(
                ).eq(PmsSpuAttrValue::getSpuId, spuId)
        );

        // 规格
        List<PmsCategorySpec> specs = iPmsCategorySpecService.listBySpuId(spuId);

        // sku
        List<PmsSku> skuList = iPmsSkuService.list(new LambdaQueryWrapper<PmsSku>().eq(PmsSku::getSpuId, spuId));

        // 评价
        List<OmsOrderCommentVo> comment = findSpuComment(spuDTO.getId(), 3);
//        orderService.findCommentBySpuId(spuDTO.getId(), 1, 3);

        // 商店信息
        BaseStoreInfo baseStoreInfo = getBaseStoreInfo(spu.getStoreId());

        AppProductBO product = AppProductBO.builder()
                .spu(spuDTO)
                .attrs(attrs)
                .specs(specs)
                .comment(comment)
                .skuList(skuList)
                .baseStoreInfo(baseStoreInfo)
                .build();
        log.info("product = {}", product);

//        AppProductBO product = new AppProductBO(spuDTO, attrs, specs, skuList, comment);
        return product;
    }

    private final StoreInfoMapper storeInfoMapper;

    private BaseStoreInfo getBaseStoreInfo(Long storeId) {
        StoreInfo storeInfo = storeInfoMapper.selectById(storeId);
        BaseStoreInfo baseStoreInfo = new BaseStoreInfo();
        BeanUtil.copyProperties(storeInfo, baseStoreInfo);
        return baseStoreInfo;
    }

    /**
     * 获取商品评价
     *
     * @param spuId spuId
     * @param limit limit
     */
    private List<OmsOrderCommentVo> findSpuComment(Long spuId, int limit) {
        List<OmsOrderComment> commentList = commentMapper.selectList(new LambdaQueryWrapper<OmsOrderComment>()
                .eq(OmsOrderComment::getSpuId, spuId)
                .eq(OmsOrderComment::getReviewStatus, ReviewStatusEnum.PASS.getCode())
                .orderByDesc(OmsOrderComment::getGmtModified)
                .orderByDesc(OmsOrderComment::getGmtCreate)
                .last("limit " + limit)
        );

        List<OmsOrderCommentVo> commentVoList = commentList.stream().map(comment -> {
            OmsOrderCommentVo vo = new OmsOrderCommentVo();
            BeanUtil.copyProperties(comment, vo);
            return vo;
        }).collect(Collectors.toList());

        for (OmsOrderCommentVo omsOrderComment : commentVoList) {
            List<OmsOrderCommentReply> replyList = replyMapper.selectList(new LambdaQueryWrapper<OmsOrderCommentReply>()
                    .eq(OmsOrderCommentReply::getOrderCommentId, omsOrderComment.getId())
            );
            List<OmsOrderCommentReplyVo> replyVoList = replyList.stream().map(reply -> {
                OmsOrderCommentReplyVo replyVo = new OmsOrderCommentReplyVo();
                BeanUtil.copyProperties(reply, replyVo);
                return replyVo;
            }).collect(Collectors.toList());

            omsOrderComment.setReplyList(replyVoList);
        }

        return commentVoList;
    }

    @Override
    public Page<ShowSpuVo> recommendList(Integer page, Integer limit) {


        // TODO 推荐逻辑先按这个来，后面再迭代
        IPage<PmsSpu> result = this.page(new Page<>(page, limit), new LambdaQueryWrapper<PmsSpu>().eq(PmsSpu::getStatus, 1)
                .orderByDesc(PmsSpu::getGmtCreate)
        );

        List<ShowSpuVo> showSpuVoList = result.getRecords().stream().map(pojo -> {
            ShowSpuVo showSpuVo = new ShowSpuVo();
            BeanUtil.copyProperties(pojo, showSpuVo);
            return showSpuVo;
        }).collect(Collectors.toList());

        Page<ShowSpuVo> voPage = new Page<>(page, limit, result.getTotal());
        voPage.setRecords(showSpuVoList);

        return voPage;
    }

    @Override
    public Boolean closeStoreSpu(String id) {
        // 清空店铺的所有商品
        boolean update = this.update(new LambdaUpdateWrapper<PmsSpu>()
                .set(PmsSpu::getStatus, 1)
                .eq(PmsSpu::getStoreId, id)
        );
        return update;
    }

    /**
     * 店家查看自己的产品
     */
    @Override
    public IPage<PmsSpu> pagePmsSpuForClerk(Integer page, Integer limit, String name, Long categoryId, Integer status, Integer reviewStatus, Integer applyFor) {
        Long userId = RequestUtils.getUserId();
        SysUserDto sysUserDto = sysUserService.getSysUserDtoById(userId);
        check(sysUserDto);

        Page<PmsSpu> pagePojo = basePage(page, limit, name, reviewStatus, sysUserDto.getStoreId(), status, applyFor, categoryId);

/**
 Page<PmsSpu> pagePojo = this.page(new Page<>(page, limit), new LambdaQueryWrapper<PmsSpu>()
 .eq(ObjectUtils.isNotEmpty(name), PmsSpu::getName, name)
 .eq(ObjectUtils.isNotEmpty(categoryId), PmsSpu::getCategoryId, categoryId)
 .eq(ObjectUtils.isNotEmpty(status), PmsSpu::getStatus, status)
 .eq(ObjectUtils.isNotEmpty(reviewStatus), PmsSpu::getReviewStatus, reviewStatus)
 .eq(ObjectUtils.isNotEmpty(applyFor), PmsSpu::getApplyFor, applyFor)
 .eq(PmsSpu::getStoreId, sysUserDto.getStoreId())
 .orderByDesc(PmsSpu::getGmtModified)
 .orderByDesc(PmsSpu::getGmtCreate)
 );
 */

        for (PmsSpu pmsSpu : pagePojo.getRecords()) {
            Long id = pmsSpu.getId();
            // sku
            List<PmsSku> skuList = iPmsSkuService.list(new LambdaQueryWrapper<PmsSku>().eq(PmsSku::getSpuId, id));
            pmsSpu.setSkuList(skuList);
        }


        log.info("pagePojo = {}", pagePojo);
        return pagePojo;
    }

    /**
     * 管理员查看所有产品
     */
    @Override
    public IPage<PmsSpu> pagePmsSpuForAdmin(Integer page, Integer limit, String name, Integer reviewStatus, Long storeId, Integer status, Integer applyFor, Long categoryId) {
        Page<PmsSpu> pagePojo = basePage(page, limit, name, reviewStatus, storeId, status, applyFor, categoryId);

        for (PmsSpu pmsSpu : pagePojo.getRecords()) {
            Long id = pmsSpu.getId();
            // sku
            List<PmsSku> skuList = iPmsSkuService.list(new LambdaQueryWrapper<PmsSku>().eq(PmsSku::getSpuId, id));
            pmsSpu.setSkuList(skuList);
        }

        log.info("pagePojo = {}", pagePojo);
        return pagePojo;
    }

    private Page<PmsSpu> basePage(Integer page, Integer limit, String name, Integer reviewStatus, Long storeId, Integer status, Integer applyFor, Long categoryId) {
        log.info("basePage(), name={},reviewStatus={},storeId={},status={},applyFor={},categoryId={}", name, reviewStatus, storeId, status, applyFor, categoryId);

        Page<PmsSpu> pagePojo = this.page(new Page<>(page, limit), new LambdaQueryWrapper<PmsSpu>()
                .like(ObjectUtils.isNotEmpty(name), PmsSpu::getName, name)
                .eq(ObjectUtils.isNotEmpty(storeId), PmsSpu::getStoreId, storeId)
                .eq(ObjectUtils.isNotEmpty(status), PmsSpu::getStatus, status)
                .eq(ObjectUtils.isNotEmpty(reviewStatus), PmsSpu::getReviewStatus, reviewStatus)
                .eq(ObjectUtils.isNotEmpty(applyFor), PmsSpu::getApplyFor, applyFor)
                .eq(ObjectUtils.isNotEmpty(categoryId), PmsSpu::getCategoryId, categoryId)
                .orderByDesc(PmsSpu::getGmtCreate)
                .orderByDesc(PmsSpu::getGmtModified)
        );
        return pagePojo;
    }

    /**
     * 商品审核通过
     */
    @Override
    public boolean reviewPass(Long id, Long userId) {

        PmsSpu pmsSpu = this.getById(id);
        // 审核通过
        boolean reviewStatus = this.update(new LambdaUpdateWrapper<PmsSpu>()
                .eq(PmsSpu::getId, id)
                .set(PmsSpu::getReviewStatus, ReviewStatusEnum.PASS.getCode()));

        // 记录操作日志
        boolean reviewLogSave = spuReviewLogService.saveLog(userId, ReviewStatusEnum.PASS.getCode(), id, pmsSpu.getStoreId(), "");

        return reviewStatus && reviewLogSave;
    }

    /**
     * 商品审核驳回
     */
    @Override
    public boolean reviewNotPass(Long userId, Long id, String remark) {
        PmsSpu pmsSpu = this.getById(id);

        // 审核驳回
        boolean updateStatus = this.update(new LambdaUpdateWrapper<PmsSpu>()
                .eq(PmsSpu::getId, id)
                .set(PmsSpu::getReviewStatus, ReviewStatusEnum.NO_PASS.getCode())
                .set(PmsSpu::getReviewRemark, remark));

        // 记录操作日志
        boolean reviewLogSave = spuReviewLogService.saveLog(userId, ReviewStatusEnum.NO_PASS.getCode(), id, pmsSpu.getStoreId(), remark);


        return updateStatus && reviewLogSave;
    }

    /**
     * 商品上架
     */
    @Override
    public boolean takeEffect(Long id) {
        Long userId = RequestUtils.getUserId();
        SysUserDto sysUserDto = sysUserService.getSysUserDtoById(userId);
        PmsSpu pmsSpu = this.getById(id);
        // 检查商品是否是自己的商品
        checkMyselfSpu(pmsSpu.getStoreId(), sysUserDto.getStoreId());

        return takeEffectOrInvalidation(id, true);
    }


    /**
     * 商品批量上架
     *
     * @param ids 商品列表
     */
    @Override
    public boolean takeEffectList(String ids) {

        Long userId = RequestUtils.getUserId();
        SysUserDto sysUserDto = sysUserService.getSysUserDtoById(userId);

//        List<String> spuIds = Arrays.asList(ids.split(","));
        List<PmsSpu> spuList = this.list(new LambdaQueryWrapper<PmsSpu>()
                .in(PmsSpu::getId, ids)
        );

        Long storeId = sysUserDto.getStoreId();
        // 检验是否是自己的商品
        for (PmsSpu spu : spuList) {
            checkMyselfSpu(spu.getStoreId(), storeId);
        }

        return takeEffectOrInvalidationList(ids, true);
    }

    /**
     * 商品下架
     */
    @Override
    public boolean invalidation(Long id) {
        Long userId = RequestUtils.getUserId();
        SysUserDto sysUserDto = sysUserService.getSysUserDtoById(userId);
        PmsSpu pmsSpu = this.getById(id);
        // 检查商品是否是自己的商品
        checkMyselfSpu(pmsSpu.getStoreId(), sysUserDto.getStoreId());

        return takeEffectOrInvalidation(id, false);
    }

    /**
     * 批量商品下架
     *
     * @param ids 商品IDs
     */
    @Override
    public boolean invalidationList(String ids) {
        Long userId = RequestUtils.getUserId();
        SysUserDto sysUserDto = sysUserService.getSysUserDtoById(userId);


        List<PmsSpu> spuList = this.list(new LambdaQueryWrapper<PmsSpu>()
                .in(PmsSpu::getId, ids)
        );

        Long storeId = sysUserDto.getStoreId();
        for (PmsSpu spu : spuList) {
            checkMyselfSpu(spu.getStoreId(), storeId);
        }

        return takeEffectOrInvalidationList(ids, false);
    }

    /**
     * 管理员批量商品下架
     *
     * @param ids 商品IDs
     */
    @Override
    public boolean adminInvalidationList(String ids) {

        return takeEffectOrInvalidationList(ids, false);
    }

    @Override
    public IPage<PmsSpu> spuListByStore(Integer page, Integer limit, Long storeId) {

        Page<PmsSpu> pagePojo = basePage(page, limit, null, ReviewStatusEnum.PASS.getCode(), storeId, 1, null, null);
        return pagePojo;
    }

    /**
     * 商品申请审核
     */
    @Override
    public boolean apply(Long id) {
        Long userId = RequestUtils.getUserId();
        SysUserDto sysUserDto = sysUserService.getSysUserDtoById(userId);
        PmsSpu pmsSpu = this.getById(id);
        // 检查商品是否是自己的商品
        checkMyselfSpu(pmsSpu.getStoreId(), sysUserDto.getStoreId());

        return this.update(new LambdaUpdateWrapper<PmsSpu>()
                .set(PmsSpu::getApplyFor, true)
                .eq(PmsSpu::getId, id)
        );
    }

    /**
     * 批量商品申请审核
     */
    @Override
    public boolean applyList(String ids) {
        Long userId = RequestUtils.getUserId();
        SysUserDto sysUserDto = sysUserService.getSysUserDtoById(userId);

        List<String> idList = Arrays.asList(ids.split(","));
        List<PmsSpu> spuList = this.list(new LambdaQueryWrapper<PmsSpu>()
                .in(PmsSpu::getId, idList)
        );

        Long storeId = sysUserDto.getStoreId();
        for (PmsSpu spu : spuList) {
            checkMyselfSpu(spu.getStoreId(), storeId);
            spu.setApplyFor(1);
        }

        log.info("spuList = {}", spuList);
        boolean update = this.updateBatchById(spuList);

        log.info("update = {}", update);
        return update;
    }

    /**
     * 批量审核通过
     */
    @Override
    public boolean reviewPassList(String ids, Long userId) {
        List<String> spuIds = Arrays.asList(ids.split(","));

        boolean updates = true;
        for (String spuId : spuIds) {
            boolean update = reviewPass(new Long(spuId), userId);
            updates = updates && update;
        }
        return updates;
    }

    /**
     * 商品上下或者下架
     *
     * @param id     id
     * @param status 上架或下架
     */
    public boolean takeEffectOrInvalidation(Long id, Boolean status) {
        boolean update = this.update(new LambdaUpdateWrapper<PmsSpu>()
                .set(PmsSpu::getStatus, status)
                .eq(PmsSpu::getId, id)
        );

        return update;
    }

    /**
     * 批量上架或下架商品
     *
     * @param ids
     * @param status
     * @return
     */
    public boolean takeEffectOrInvalidationList(String ids, Boolean status) {

        boolean update = this.update(new LambdaUpdateWrapper<PmsSpu>()
                .set(PmsSpu::getStatus, status)
                .in(PmsSpu::getId, ids)
        );
        log.info("ids = {},status = {} ,update = {} ", ids, status, update);

        // TODO by Martin 消息通知商家
        // TODO by Martin 记录商家档案
        return update;
    }


    private void checkMyselfSpu(Long spuStoreId, Long userStoreId) {
        if (!userStoreId.equals((long) spuStoreId)) {
            throw new BizException("权限不足,您只能管理自己的商品");
        }
    }

}
